package com.logos.musicframe.utils;

import com.logos.musicframe.controller.SongPlayHistoryController;
import com.logos.musicframe.controller.SongsController;
import com.logos.musicframe.resp.SongsResp;
import com.logos.musicframe.result.Result;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.embed.swing.JFXPanel;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.util.Duration;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author logos
 * date 2025/5/29 22:48
 * @version v1.0
 * @Package com.logos.musicframe.utils
 */
@Component
@Slf4j
public class JavaFxMusicPlayer implements InitializingBean {

    // 添加SongPlayHistoryController依赖
    @Autowired
    private SongPlayHistoryController songPlayHistoryController;

    @Autowired
    private SongsController songsController;

    // 播放器状态监听器接口
    public interface PlayerStatusListener {
        void onPlayerStatusChanged(MediaPlayer mediaPlayer);
    }
    
    // 自动播放下一首监听器接口
    public interface PlayerAutoNextListener extends PlayerStatusListener {
        void onAutoPlayNext(int currentIndex);
    }
    
    // 状态监听器列表
    private List<PlayerStatusListener> statusListeners = new ArrayList<>();
    
    // 添加状态监听器
    public void addPlayerStatusListener(PlayerStatusListener listener) {
        statusListeners.add(listener);
        // 如果播放器已存在，立即通知新添加的监听器
        if (player != null) {
            listener.onPlayerStatusChanged(player);
        }
    }
    
    // 移除状态监听器
    public void removePlayerStatusListener(PlayerStatusListener listener) {
        statusListeners.remove(listener);
    }
    
    // 通知所有监听器状态变化
    private void notifyStatusListeners() {
        for (PlayerStatusListener listener : statusListeners) {
            listener.onPlayerStatusChanged(player);
        }
    }

    // 是否正在播放
    public boolean isPlaying = false;

    private MediaPlayer player;

    public synchronized void play(String mediaPath) {
        if (isPlaying) {
            // 如果已经在播放，则先停止
            stop();
        }
        
        // 更新当前索引（如果该路径在播放列表中）
        if (!playlist.isEmpty() && mediaPath != null) {
            for (int i = 0; i < playlist.size(); i++) {
                if (mediaPath.equals(playlist.get(i))) {
                    currentIndex = i;
                    break;
                }
            }
        }
        
        // 记录播放历史
        if (mediaPath != null && !mediaPath.isEmpty()) {
            // 异步记录播放历史，避免阻塞主线程
            String finalMediaPath = mediaPath;
            new Thread(() -> {
                try {
                    // 根据文件路径查询歌曲信息
                    Result<SongsResp> result = songsController.querySongByPath(finalMediaPath);
                    if (result.isSuccess() && result.getData() != null) {
                        SongsResp song = result.getData();
                        // 记录播放历史
                        songPlayHistoryController.add(song.getId());
                    } else {
                        log.warn("无法记录播放历史，未找到歌曲信息: {}", finalMediaPath);
                    }
                } catch (Exception e) {
                    log.error("记录播放历史失败: {}", e.getMessage(), e);
                }
            }).start();
        }
        
        // 定位.mp3结尾位置
        int mp3Index = mediaPath.indexOf(".mp3");
        if (mp3Index != -1) {
            // 精确截取到.mp3结尾
            mediaPath = mediaPath.substring(0, mp3Index + 4);
        }
        mediaPath.trim();
        // 检查结尾字符的Unicode值
        char lastChar = mediaPath.charAt(mediaPath.length() - 1);
        int lastCode = lastChar;
        log.info("Last char code: {}",lastCode);
        try {
            // 手动替换空格
            mediaPath = new URI(mediaPath.replace(" ", "%20")).toString();
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }
        log.info("MediaPlayer播放音乐：{}",mediaPath);
        try {
            Media media;
            if (mediaPath.startsWith("https")|| mediaPath.startsWith("http")) {
                // 网络地址直接作为 Media 构造参数
                media = new Media(mediaPath);
            } else {
                // 本地文件路径转换为 file:// URI
                String decodedPath = URLDecoder.decode(mediaPath, StandardCharsets.UTF_8);
                File file = new File(decodedPath);
                if (!file.exists()) {
                    System.err.println("文件不存在: " + file.getAbsolutePath());
                    return;
                }
                media = new Media(file.toURI().toString());
            }

            player = new MediaPlayer(media);
            
            // 通知所有监听器播放器状态变化
            notifyStatusListeners();

            // 设置播放状态监听
            player.setOnPlaying(() -> {
                isPlaying = true;
                notifyStatusListeners();
            });
            
            player.setOnPaused(() -> {
                isPlaying = false;
                notifyStatusListeners();
            });
            
            player.setOnStopped(() -> {
                isPlaying = false;
                notifyStatusListeners();
            });
            
            player.setOnEndOfMedia(() -> {
                switch (repeatMode) {
                    case SINGLE:
                        // 单曲循环：重新从头开始播放当前歌曲
                        player.seek(Duration.ZERO);
                        player.play();
                        break;
                    case SHUFFLE:
                    case PLAYLIST:
                    default:
                        // 播放下一首
                        if (!playlist.isEmpty() && currentIndex >= 0) {
                            // 在新线程中执行，避免阻塞媒体线程
                            new Thread(() -> {
                                boolean success = playNext();
                                // 通知播放器状态变化（用于更新UI）
                                if (success) {
                                    // 如果成功播放了下一首，触发一个特殊的事件通知UI更新
                                    for (PlayerStatusListener listener : statusListeners) {
                                        if (listener instanceof PlayerAutoNextListener) {
                                            ((PlayerAutoNextListener) listener).onAutoPlayNext(currentIndex);
                                        }
                                    }
                                }
                            }).start();
                        } else {
                            // 没有播放列表，停止播放
                            isPlaying = false;
                            player.stop();
                            notifyStatusListeners();
                        }
                        break;
                }
            });

            // 在子线程中播放，避免阻塞 UI
            new Thread(() -> {
                isPlaying = true;
                player.play();
            }).start();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public synchronized void pause() {
        if (player != null && isPlaying) {
            player.pause();
            isPlaying = false;
        }
    }

    public synchronized void stop() {
        if (player != null) {
            player.stop();
            player = null;
            isPlaying = false;
        }
    }

    public void setVolume(double volume) {
        if (player != null) {
            // 音量范围：0.0 ~ 1.0
            player.setVolume(volume);
        }
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        new JFXPanel(); // 初始化 JavaFX 环境
    }


    /**
     * 获取当前播放器实例（供 UI 拖拽进度条使用）
     */
    public MediaPlayer getMediaPlayer() {
        return player;
    }

    /**
     * 跳转到指定时间点（秒）
     */
    public void seek(double seconds) {
        if (player != null) {
            player.seek(Duration.seconds(seconds));
        }
    }

    /**
     * 获取当前播放时间
     */
    public Duration getCurrentTime() {
        if (player != null) {
            return player.getCurrentTime();
        }
        return Duration.ZERO;
    }

    /**
     * 获取总时长
     */
    public Duration getTotalDuration() {
        if (player != null && player.getMedia() != null) {
            return player.getMedia().getDuration();
        }
        return Duration.ZERO;
    }

    // 循环模式枚举
    public enum RepeatMode {
        PLAYLIST,  // 列表循环
        SINGLE,    // 单曲循环
        SHUFFLE    // 随机播放
    }
    
    // 当前循环模式
    private RepeatMode repeatMode = RepeatMode.PLAYLIST;
    
    // 当前播放列表
    private List<String> playlist = new ArrayList<>();
    
    // 当前播放索引
    private int currentIndex = -1;
    
    /**
     * 设置循环模式
     * @param mode 循环模式
     */
    public void setRepeatMode(RepeatMode mode) {
        this.repeatMode = mode;
        log.info("设置循环模式: {}", mode);
    }
    
    /**
     * 获取当前循环模式
     * @return 当前循环模式
     */
    public RepeatMode getRepeatMode() {
        return repeatMode;
    }

    /**
     * 设置播放列表
     * @param filePaths 文件路径列表
     */
    public void setPlaylist(List<String> filePaths) {
        if (filePaths != null) {
            this.playlist = new ArrayList<>(filePaths);
            log.info("设置播放列表，共{}首歌曲", playlist.size());
        }
    }
    
    /**
     * 播放列表中的指定索引歌曲
     * @param index 索引
     * @return 是否成功播放
     */
    public boolean playByIndex(int index) {
        if (playlist.isEmpty() || index < 0 || index >= playlist.size()) {
            log.warn("无法播放索引{}的歌曲，播放列表为空或索引越界", index);
            return false;
        }
        
        currentIndex = index;
        String filePath = playlist.get(currentIndex);
        play(filePath);
        log.info("播放列表中第{}首歌曲: {}", currentIndex + 1, filePath);
        return true;
    }
    
    /**
     * 播放下一首
     * @return 是否成功播放下一首
     */
    public boolean playNext() {
        if (playlist.isEmpty()) {
            log.warn("播放列表为空，无法播放下一首");
            return false;
        }
        
        int nextIndex;
        
        if (repeatMode == RepeatMode.SHUFFLE) {
            // 随机模式：随机选择一首（排除当前歌曲）
            if (playlist.size() == 1) {
                nextIndex = 0; // 只有一首歌时，仍然播放这首
            } else {
                int randomIndex;
                do {
                    randomIndex = (int) (Math.random() * playlist.size());
                } while (randomIndex == currentIndex && playlist.size() > 1);
                nextIndex = randomIndex;
            }
        } else {
            // 列表循环或单曲循环模式：顺序播放下一首
            nextIndex = (currentIndex + 1) % playlist.size();
        }
        
        return playByIndex(nextIndex);
    }
    
    /**
     * 播放上一首
     * @return 是否成功播放上一首
     */
    public boolean playPrevious() {
        if (playlist.isEmpty()) {
            log.warn("播放列表为空，无法播放上一首");
            return false;
        }
        
        int prevIndex;
        
        if (repeatMode == RepeatMode.SHUFFLE) {
            // 随机模式：随机选择一首（排除当前歌曲）
            if (playlist.size() == 1) {
                prevIndex = 0; // 只有一首歌时，仍然播放这首
            } else {
                int randomIndex;
                do {
                    randomIndex = (int) (Math.random() * playlist.size());
                } while (randomIndex == currentIndex && playlist.size() > 1);
                prevIndex = randomIndex;
            }
        } else {
            // 列表循环或单曲循环模式：顺序播放上一首
            prevIndex = (currentIndex - 1 + playlist.size()) % playlist.size();
        }
        
        return playByIndex(prevIndex);
    }
    
    /**
     * 获取当前播放索引
     * @return 当前播放索引
     */
    public int getCurrentIndex() {
        return currentIndex;
    }
    
    /**
     * 获取当前播放列表
     * @return 当前播放列表
     */
    public List<String> getPlaylist() {
        return new ArrayList<>(playlist);
    }
}
//// error
//MediaPlayer播放音乐：https://music-player-bucket.oss-cn-beijing.aliyuncs.com/aa79a661-5efc-4f7a-af98-3b8bf4dd1b77.mp3
//MediaPlayer播放音乐：https://music-player-bucket.oss-cn-beijing.aliyuncs.com/101f5d3a-9b75-4c72-bcb4-bcb48084110c.mp3
//// right
//MediaPlayer播放音乐：https://music-player-bucket.oss-cn-beijing.aliyuncs.com/f2724ed1-7a9a-449a-aac8-cb74f8cbb86f.mp3

